package com.edu.system.service.impl;

import com.alibaba.fastjson2.JSONObject;
import com.edu.common.exception.ServiceException;
import com.edu.common.utils.StringUtils;
import com.edu.common.utils.bean.BeanValidators;
import com.edu.system.domain.CardUser;
import com.edu.system.domain.TCard;
import com.edu.system.domain.TClass;
import com.edu.system.mapper.CardUserMapper;
import com.edu.system.service.CardUserService;
import com.edu.system.service.ITCardService;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;
import javax.annotation.Resource;
import javax.validation.Validator;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * 卡
 *
 * @author xxxx
 * @date 2023-12-17
 */
@Slf4j
@Service
public class CardUserServiceImpl implements CardUserService {

    @Resource
    private CardUserMapper cardUserMapper;
    @Autowired
    protected Validator validator;
    @Resource
    private ITCardService itCardService;

    private static final Integer cardType_student = 0;
    private static final Integer cardType_teacher = 1;

    private static final Integer STATUS_0 = 0;
    private static final Integer STATUS_1 = 1;

    @Override
    public List<CardUser> selectList(CardUser user) {
        List<CardUser> cardUsers = new ArrayList<>();
        if (user.getType().equals(cardType_teacher)){
            cardUsers = cardUserMapper.selectTeacherList(user);
        } else {
            cardUsers = cardUserMapper.selectStudentList(user);
            for (CardUser u : cardUsers){
                u.setClassName(joinClassName(u));
            }
        }
        return cardUsers;
    }

    private String joinClassName(CardUser c) {
        if (StringUtils.isNull(c.getGeneration())){
            return c.getGeneration();
        }
        return c.getGeneration().contains("届") ? c.getClassName() : c.getGeneration() + "届" + c.getClassName();
    }

    @Override
    public CardUser selectByCardId(Long cardId) {
        TCard card = itCardService.selectTCardById(cardId);
        CardUser user = new CardUser();
        user.setType(card.getType());
        user.setId(cardId);
        return Optional.ofNullable(this.selectList(user))
            .filter(CollectionUtils::isNotEmpty)
            .map(a -> a.get(0))
            .orElseGet(() -> null);
    }

    @Transactional
    @Override
    public String rechargeByList(List<CardUser> list) {
        if (StringUtils.isNull(list) || list.size() == 0) {
            throw new ServiceException("导入数据不能为空！");
        }
        AtomicInteger successNum = new AtomicInteger();
        AtomicInteger failureNum = new AtomicInteger();
        StringBuilder successMsg = new StringBuilder();
        StringBuilder failureMsg = new StringBuilder();

        list.forEach(c -> {
            try {
                BeanValidators.validateWithException(validator, c);
                // 验证
                TCard card = itCardService.checkIsExist(c.getOwnerId(), c.getOwner());
                if (StringUtils.isNotNull(card) && StringUtils.isNotEmpty(card.getCardNo())) {
//                    c.setCardNo(card.getCardNo());
                    successNum.getAndIncrement();
                } else {
                    failureNum.getAndIncrement();
                    failureMsg.append("<br/>" + failureNum + "、卡 " + c.getOwner() + " 的卡未找到或卡号不存在");
                }
            } catch (Exception e) {
                failureNum.getAndIncrement();
                String msg = "<br/>" + failureNum + "、卡 " + c.getOwner() + " 充值校验失败：";
                failureMsg.append(msg + e.getMessage());
                log.error(msg, e);
            }
        });
        if (failureNum.get() > 0) {
            failureMsg.insert(0, "上传失败，部分校验失败！共 " + failureNum + " 条数据，错误如下：");
            throw new ServiceException(failureMsg.toString());
        } else {
            successMsg.insert(0, "全部充值成功！共 " + successNum + " 条");
        }

        log.info(JSONObject.toJSONString(list));
        // 处理充值
        list.forEach(c -> {
            itCardService.recharge(Collections.singletonList(c.getCardNo()), c.getBalance());
        });
        return successMsg.toString();
    }

    @Override
    public String recharge(List<Long> cardIds, Float amount) {
        List<TCard> list = itCardService.selectCardByIds(cardIds);
        List<TCard> collect = list.stream()
            .filter(a -> a.getStatus().equals(STATUS_1))
            .collect(Collectors.toList());
        if (CollectionUtils.isNotEmpty(collect)){
            throw new ServiceException("挂失的卡不能被充值");
        }
        List<String> nos = list
            .stream()
            .map(TCard::getCardNo)
            .collect(Collectors.toList());
        int recharge = itCardService.recharge(nos, amount);
        return String.valueOf(recharge);
    }

    @Override
    public long getCardCnt() {
        return cardUserMapper.cardCnt();
    }


}
